Skip to content

✨ Feat: add Thin Waist address validation utilities and integrate into echo example #811

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

yashksaini-coder
Copy link

What was wrong?

There was no integration for thin waist address validation.

Issue #804

How was it fixed?

Implements Phase 1 & partial Phase 2 of issue #804 by introducing Thin Waist Address Validation utilities and updating the echo example to use them, Using the multiaddr.

  1. New utility module: libp2p/utils/address_validation.py
    • get_available_interfaces
    • get_optimal_binding_address
    • expand_wildcard_address
    • Safe fallbacks when Thin Waist functions are not present in multiaddr.utils
  2. Re-exported utilities in libp2p/utils/__init__.py
  3. Updated examples/echo/echo.py:
    • Replaced hardcoded /ip4/0.0.0.0/tcp/{port} with get_optimal_binding_address
    • Added interface discovery logging
  4. Added advanced demo: examples/advanced/network_discovery.py
  5. Added tests:
    • tests/utils/test_address_validation.py
    • tests/examples/test_echo_thin_waist.py (light integration)

Why

  • Enables dynamic discovery of bindable interfaces (IPv4 & IPv6 where available)
  • Provides a clean abstraction for examples to avoid hardcoding wildcard addresses
  • Demonstrates best practices for future example migrations
  • Maintains backward compatibility (graceful fallbacks if Thin Waist APIs not installed)

Backward Compatibility

  • If multiaddr.utils.get_thin_waist_addresses / get_network_addrs are unavailable, utilities fallback to conservative defaults.
  • Existing behavior (binding on wildcard / loopback) still achievable.

To-Do

  • Utilities implemented with safe fallbacks
  • Echo example migrated
  • Tests added & passing locally
  • No breaking public API changes
  • Clean up commit history
  • Add or update documentation related to these changes
  • Add entry to the release notes

yashksaini-coder added 3 commits August 9, 2025 01:22
…tilities

- Added `network_discover.py` to demonstrate Thin Waist address handling.
- Introduced `address_validation.py` with functions for discovering available network interfaces, expanding wildcard addresses, and determining optimal binding addresses.
- Included fallback mechanisms for environments lacking Thin Waist support.
- Replaced hardcoded listen address with `get_optimal_binding_address` for improved flexibility.
- Imported address validation utilities in `echo.py` and updated `__init__.py` to include new functions.
- Introduced `test_echo_thin_waist.py` to validate the echo example's output for Thin Waist lines.
- Added `test_address_validation.py` to cover functions for available interfaces, optimal binding addresses, and wildcard address expansion.
- Included parameterized tests and environment checks for IPv6 support.
@acul71
Copy link
Contributor

acul71 commented Aug 9, 2025

Hi @yashksaini-coder, ping me if you need help.
you can run make PR and make docs to check everything is ok

@yashksaini-coder
Copy link
Author

Hi @yashksaini-coder, ping me if you need help. you can run make PR and make docs to check everything is ok

Right now, I've created a draft PR to introduce the multiadd thin waist address. with integration to examples and tests, could you give me feedback on this approach. I've only done Phase 1 + 2 (partially) based on the issue #804

@@ -0,0 +1,51 @@
import asyncio
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use Trio we don't use asyncio (for uniformity in all code base)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okh got it

@acul71
Copy link
Contributor

acul71 commented Aug 10, 2025

@yashksaini-coder

Can you modify echo.py so that it "mimic" javascript echo, exposing all available interfaces?

  • Current echo.py
(venv) luca@r17:~/PNL_Launchpad_Curriculum/Libp2p/tmp/yashksaini-coder/py-libp2p$ python examples/echo/echo.py
I am 16Uiu2HAmRxqPcNXm9KAUAVKyQkpXF8c8r7S6jdpGK6K963w9Puwk
Run this from the same folder in another console:

echo-demo -d /ip4/192.168.136.148/tcp/33387/p2p/16Uiu2HAmRxqPcNXm9KAUAVKyQkpXF8c8r7S6jdpGK6K963w9Puwk

Waiting for incoming connections...
  • javascript echo
luca@r17:~/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-examples/examples/js-libp2p-example-chat$ node src/listener.js 
Listener ready, listening on:
/ip4/127.0.0.1/tcp/10333/p2p/12D3KooWCS6QSMEbtt77pWeB618W824aGVxhLhPEPaCUMGMvBhuk
/ip4/192.168.136.148/tcp/10333/p2p/12D3KooWCS6QSMEbtt77pWeB618W824aGVxhLhPEPaCUMGMvBhuk
/ip4/10.149.6.41/tcp/10333/p2p/12D3KooWCS6QSMEbtt77pWeB618W824aGVxhLhPEPaCUMGMvBhuk
  • Desired python echo
echo.py
I am 16Uiu2HAmRxqPcNXm9KAUAVKyQkpXF8c8r7S6jdpGK6K963w9Puwk
Listener ready, listening on:
/ip4/127.0.0.1/tcp/10333/p2p/16Uiu2HAmRxqPcNXm9KAUAVKyQkpXF8c8r7S6jdpGK6K963w9Puwk
/ip4/192.168.136.148/tcp/10333/p2p/16Uiu2HAmRxqPcNXm9KAUAVKyQkpXF8c8r7S6jdpGK6K963w9Puwk
/ip4/10.149.6.41/tcp/10333/p2p/16Uiu2HAmRxqPcNXm9KAUAVKyQkpXF8c8r7S6jdpGK6K963w9Puwk

Run this from the same folder in another console:

echo-demo -d /ip4/192.168.136.148/tcp/33387/p2p/16Uiu2HAmRxqPcNXm9KAUAVKyQkpXF8c8r7S6jdpGK6K963w9Puwk

Waiting for incoming connections...

@yashksaini-coder
Copy link
Author

@yashksaini-coder

Can you modify echo.py so that it "mimic" javascript echo, exposing all available interfaces?

  • Current echo.py
(venv) luca@r17:~/PNL_Launchpad_Curriculum/Libp2p/tmp/yashksaini-coder/py-libp2p$ python examples/echo/echo.py
I am 16Uiu2HAmRxqPcNXm9KAUAVKyQkpXF8c8r7S6jdpGK6K963w9Puwk
Run this from the same folder in another console:

echo-demo -d /ip4/192.168.136.148/tcp/33387/p2p/16Uiu2HAmRxqPcNXm9KAUAVKyQkpXF8c8r7S6jdpGK6K963w9Puwk

Waiting for incoming connections...
  • javascript echo
luca@r17:~/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-examples/examples/js-libp2p-example-chat$ node src/listener.js 
Listener ready, listening on:
/ip4/127.0.0.1/tcp/10333/p2p/12D3KooWCS6QSMEbtt77pWeB618W824aGVxhLhPEPaCUMGMvBhuk
/ip4/192.168.136.148/tcp/10333/p2p/12D3KooWCS6QSMEbtt77pWeB618W824aGVxhLhPEPaCUMGMvBhuk
/ip4/10.149.6.41/tcp/10333/p2p/12D3KooWCS6QSMEbtt77pWeB618W824aGVxhLhPEPaCUMGMvBhuk
  • Desired python echo
echo.py
I am 16Uiu2HAmRxqPcNXm9KAUAVKyQkpXF8c8r7S6jdpGK6K963w9Puwk
Listener ready, listening on:
/ip4/127.0.0.1/tcp/10333/p2p/16Uiu2HAmRxqPcNXm9KAUAVKyQkpXF8c8r7S6jdpGK6K963w9Puwk
/ip4/192.168.136.148/tcp/10333/p2p/16Uiu2HAmRxqPcNXm9KAUAVKyQkpXF8c8r7S6jdpGK6K963w9Puwk
/ip4/10.149.6.41/tcp/10333/p2p/16Uiu2HAmRxqPcNXm9KAUAVKyQkpXF8c8r7S6jdpGK6K963w9Puwk

Run this from the same folder in another console:

echo-demo -d /ip4/192.168.136.148/tcp/33387/p2p/16Uiu2HAmRxqPcNXm9KAUAVKyQkpXF8c8r7S6jdpGK6K963w9Puwk

Waiting for incoming connections...

Got it exposing all available interfaces. @acul71

@acul71
Copy link
Contributor

acul71 commented Aug 10, 2025

@yashksaini-coder
Great work just follow this mods:

Summary: yashksaini-coder's Thin Waist Address Validation PR

🎯 Quick Assessment

Overall: Excellent foundation, needs minor refinements for JavaScript parity.

Status: Phase 1 ✅ Complete, Phase 2 🔄 Partially Complete

What's Working Well

  • Core utilities: Robust, well-tested, proper error handling
  • Backward compatibility: Graceful fallbacks when Thin Waist unavailable
  • Test coverage: Comprehensive unit and integration tests
  • Type safety: Full type annotations throughout

🔧 Key Issues to Fix

1. JavaScript Parity (High Priority)

Problem: Echo shows only 1 address instead of multiple interfaces like JS libp2p.

Current:

/ip4/192.168.136.148/tcp/8000/p2p/16Uiu2...

Target (like JS):

/ip4/127.0.0.1/tcp/8000/p2p/16Uiu2...
/ip4/192.168.136.148/tcp/8000/p2p/16Uiu2...
/ip4/10.149.6.41/tcp/8000/p2p/16Uiu2...

Fix: Use get_available_interfaces() instead of get_optimal_binding_address()

2. Missing Loopback (High Priority)

Problem: No 127.0.0.1 in output.

Fix: Add loopback to get_available_interfaces():

addrs.append(Multiaddr(f"/ip4/127.0.0.1/{protocol}/{port}"))

3. Command Display (Medium Priority)

Problem: echo-demo -d shows 0.0.0.0 instead of concrete address.

Fix: Use first expanded address instead of host.get_addrs()[0]

🚀 Quick Wins

  1. Replace this line in echo.py:

    listen_addr = get_optimal_binding_address(port)

    With:

    listen_addrs = get_available_interfaces(port)
  2. Add loopback to address validation:

    # In get_available_interfaces()
    addrs.append(Multiaddr(f"/ip4/127.0.0.1/{protocol}/{port}"))
  3. Update display logic:

    # Show all addresses
    for addr in listen_addrs:
        print(f"{addr}/p2p/{host.get_id().to_string()}")

📋 Action Items

High Priority

  • Fix JavaScript parity (multiple interface display)
  • Add loopback interface (127.0.0.1)
  • Fix command generation (use concrete addresses)

Medium Priority

  • Improve random port handling
  • Add IPv6 loopback support
  • Enhanced error messages

🏆 Recommendation

Approve with minor revisions. The core implementation is solid - just needs these small tweaks to match JavaScript libp2p behavior.

🧪 Test Status

Unit Tests - All Passing

  • test_get_available_interfaces()
  • test_get_optimal_binding_address()
  • test_expand_wildcard_address_ipv4()
  • test_expand_wildcard_address_port_override()
  • test_expand_wildcard_address_ipv6()

Integration Test - Failing

Problem: test_echo_thin_waist.py expects log messages that don't exist in current echo.py.

Test expects:

"Selected binding address:"
"Available candidate interfaces:"

Current echo.py outputs:

"I am {peer_id}"
"echo-demo -d {address}"
"Waiting for incoming connections..."

Fix: Update integration test to match actual echo.py output format.

💡 Pro Tips

  1. Test with: python examples/echo/echo.py -p 8000
  2. Compare with: JavaScript libp2p output format
  3. Focus on: User experience consistency across implementations
  4. Remember: Loopback is crucial for local development

Bottom Line: Great work! Just need to show all interfaces like JavaScript libp2p does. 🚀

@yashksaini-coder
Copy link
Author

@acul71 got it this clears a lot, I will focus on the javascript libp2p interface showcase.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants